package com.gitee.wsl.text


import kotlin.jvm.JvmOverloads


/**
 * 此类使用转义字符时请注意不能使用单引号、双引号、圆括号、中括号和大括号。 此类支持转义字符\，即\后的引号与括号不起作用，将被跳过
 */
class Sentence {
    /**
     * 构造函数
     *
     * @param str
     * 需要进行句法分析的字符串
     */
    constructor(str: String) {
        this.sentence = str
    }

    /**
     * 构造函数
     *
     * @param str
     * 需要进行句法分析的字符串
     * @param escapeChar
     * 转义字符
     */
    constructor(str: String, escapeChar: Char) {
        this.sentence = str
        this.escapeChar = escapeChar
    }

    /**
     * 搜索下一个匹配的引号'或"
     *
     * @param start
     * 起始位置,即头一引号在原串中的位置
     * @return 下一个匹配的引号在原串中的位置
     */
    fun scanQuotation(start: Int): Int {
        return scanQuotation(this.sentence, start, escapeChar)
    }

    /**
     * 将原串中的空白字符删除,并根据ifcase参数将原串中的非引号内字符大写,小写或不动， 将getSentence()返回的串更改为结果串
     *
     * @param ifcase
     * 可以为0, UPPER_WHEN_TRIM, LOWER_WHEN_TRIM及其加法组合
     * @return 删除空白字符后的串
     */
    fun trim(ifcase: Int) {
        this.sentence = trim(this.sentence, ifcase, escapeChar)
    }

    /**
     * 在原串中搜索短语
     *
     * @param phrase
     * 需要搜索的短语
     * @param start
     * 在原串中的起始位置
     * @param flag
     * 可以为0,IGNORE_CASE,IGNORE_PARS,IGNORE_CASE+IGNORE_PARS
     * @return 短语在原串中的位置
     */
    fun phraseAt(phrase: String, start: Int, flag: Int): Int {
        return phraseAt(this.sentence, phrase, start, flag, escapeChar)
    }

    /**
     * 替换原串中的子串，并将getSentence()返回的字符串更改为结果串
     *
     * @param start
     * 对原串开始替换的起始位置
     * @param sold
     * 需要替换的子串
     * @param snew
     * 替换串
     * @param flag
     * 可为0,IGNORE_CASE,IGNORE_PARS,ONLY_FIRST,ONLY_PHRASE及其加法组合
     * @return 被替换子串的个数
     */
    fun replace(start: Int, sold: String, snew: String?, flag: Int): Int {
        val strlen = sentence.length
        val len = sold.length
        var count = 0
        var dst: StringBuilder? = null
        var preChar = '*' // 指示匹配串前一个字符不是有效标识符字符
        var i = start
        while (i < strlen) {
            val ch = sentence[i]
            if ((ch == '\"' || ch == '\'')
                && ((i > 0 && sentence[i - 1] != '\\') || i == 0)
            ) {
                var idx = scanQuotation(sentence, i, escapeChar)
                if (idx < 0) return 0
                idx++
                if (dst != null) for (j in i until idx) dst.append(sentence[j])
                i = idx
                preChar = '*'
                continue
            }
            if (((flag and IGNORE_PARS) == 0) && (ch == '(')) {
                var idx = scanParenthesis(sentence, i, escapeChar)
                if (idx < 0) return 0
                idx++
                if (dst != null) for (j in i until idx) dst.append(sentence[j])
                i = idx
                preChar = '*'
                continue
            }

            var lb: Boolean
            lb = sold.regionMatches(0, sentence, i, len, ignoreCase = (flag and IGNORE_CASE) > 0)
            if (lb && (flag and ONLY_PHRASE) > 0) {
                // 被匹配串的第一字符及前一字符有一个不是标识符字符时为真
                lb = !isWordChar(sold[0]) || !isWordChar(preChar)
                // 被匹配串的最后字符及后一字符有一个不是标识符字符时
                if ((i + len) < strlen) lb = (lb
                        && (!isWordChar(sold[len - 1]) || !isWordChar(
                    sentence[i + len]
                )))
            }
            if (lb) {
                if (dst == null) {
                    dst = StringBuilder(strlen shl 2)
                    for (j in 0 until i) dst.append(sentence[j])
                }
                dst.append(snew)
                i += len
                preChar = sentence[i - 1]
                count++
                if ((flag and ONLY_FIRST) > 0) {
                    while (i < strlen) dst.append(sentence[i++])
                    break
                }
            } else {
                if (dst != null) dst.append(ch)
                i++
            }
        }
        if (dst != null) sentence = dst.toString()
        return count
    }

    /**
     * 取分析后的串
     *
     * @return 分析后的串
     */
    override fun toString(): String {
        return this.sentence
    }

    fun indexOf(find: String, start: Int, flag: Int): Int {
        return indexOf(this.sentence, find, start, flag, escapeChar)
    }

    /**
     * 取分析后的串
     *
     * @return 分析后的串
     */
    var sentence: String
        private set
    private var escapeChar = '\\'

    companion object {
        /**
         * 搜索时忽略大小写
         */
        const val IGNORE_CASE: Int = 1

        /**
         * 搜索时忽略圆括号,即要扫描括号中内容
         */
        const val IGNORE_PARS: Int = 2

        /**
         * 搜索时仅仅查找第一个匹配串
         */
        const val ONLY_FIRST: Int = 4

        /**
         * 搜索时仅仅在匹配串是标识符时成功
         */
        const val ONLY_PHRASE: Int = 8

        /**
         * 搜索时忽略引号,即要扫描引号中内容
         */
        const val IGNORE_QUOTE: Int = 16

        /**
         * 指示删除字符串中空白字符时将引号外的字符大写
         */
        const val UPPER_WHEN_TRIM: Int = 16

        /**
         * 指示删除字符串中空白字符时将引号外的字符小写
         */
        const val LOWER_WHEN_TRIM: Int = 32

        private const val LOG = false

        fun log(o: Any?) {
            if (LOG) println(o)
        }

        /**
         * 搜索标识符
         *
         * @param str
         * 需要搜索标识的原串
         * @param start
         * 搜索的起始位置
         * @return 返回标识符最后一个字符在原串中的位置
         */
        /*fun scanIdentifier(str: String, start: Int): Int {
            val len = str.length
            var ch = str[start]
            if (!java.lang.Character.isJavaIdentifierStart(ch)) return -1
            var i = start + 1
            while (i < len) {
                ch = str[i]
                if (ch == 0.toChar()) break
                if (ch == 1.toChar()) break
                if (!java.lang.Character.isJavaIdentifierPart(ch)) break
                i++
            }
            return i - 1
        }*/

        /*fun checkIdentifier(ident: String?): Boolean {
            if (ident == null) return false
            val len = ident.length
            if (len == 0) return false
            var c = ident[0]
            if (!java.lang.Character.isJavaIdentifierStart(c)) return false

            for (i in 1 until len) {
                c = ident[i]
                if (c == 0.toChar()) return false
                if (c == 1.toChar()) return false
                if (!java.lang.Character.isJavaIdentifierPart(c)) return false
            }
            return true
        }*/


        /**
         * 搜索下一个匹配的引号'或",缺省转义字符为\
         *
         * @param str
         * 需要搜索引号的原串
         * @param start
         * 起始位置,即头一引号在原串中的位置
         * @return 若找到,则返回匹配的引号在原串中的位置,否则返回-1
         */
        @JvmOverloads
        fun scanQuotation(str: String, start: Int, escapeChar: Char = '\\'): Int {
            val quote = str[start]
            if (quote != '\"' && quote != '\'') return -1
            var idx = start + 1
            val len = str.length
            while (idx < len) {
                /*
			 * idx = str.indexOf(quote, idx); if (idx < 0) break; if (
			 * str.charAt(idx - 1) != escapeChar) return idx; idx++;
			 */
                val ch = str[idx]
                if (ch == escapeChar) idx += 2
                else if (ch == quote) return idx
                else idx++
            }
            return -1
        }


        /**
         * 搜索下一个匹配的圆括号,缺省转义字符为\，且引号内的圆括号被跳过
         *
         * @param str
         * 需要搜索括号的原串
         * @param start
         * 起始位置,即左圆括号(在原串中的位置
         * @return 若找到,则返回匹配的右圆括号在原串中的位置,否则返回-1
         */
        @JvmOverloads
        fun scanParenthesis(str: String, start: Int, escapeChar: Char = '\\'): Int {
            if (str[start] != '(') return -1

            val len = str.length
            var i = start + 1
            var q = -1
            while (i < len) {
                val ch = str[i]
                when (ch) {
                    '(' -> {
                        i = scanParenthesis(str, i, escapeChar)
                        if (i < 0) return -1
                        i++
                    }

                    '\"', '\'' -> {
                        q = scanQuotation(str, i, escapeChar)
                        if (q < 0) {
                            i++
                        } else {
                            i = q + 1
                        }
                    }

                    '[' -> if (i > start && str[i - 1] == '$') {
                        q = scanBracket(str, i, escapeChar)
                        if (q < 0) {
                            i++
                        } else {
                            i = q + 1
                        }
                    } else {
                        i++
                    }

                    ')' -> return i
                    else -> {
                        if (ch == escapeChar) i++
                        i++
                    }
                }
            }
            return -1
        }


        /**
         * 搜索下一个匹配的中括号,缺省转义字符为\，且引号内的中括号被跳过
         *
         * @param str
         * 需要搜索括号的原串
         * @param start
         * 起始位置,即左中括号在原串中的位置
         * @return 若找到,则返回匹配的右中括号在原串中的位置,否则返回-1
         */
        @JvmOverloads
        fun scanBracket(str: String, start: Int, escapeChar: Char = '\\'): Int {
            if (str[start] != '[') return -1

            val len = str.length
            var i = start + 1
            while (i < len) {
                val ch = str[i]
                when (ch) {
                    '[' -> {
                        i = scanBracket(str, i, escapeChar)
                        if (i < 0) return -1
                        i++
                    }

                    '\"', '\'' -> {
                        val q = scanQuotation(str, i, escapeChar)
                        if (q < 0) {
                            i++
                        } else {
                            i = q + 1
                        }
                    }

                    ']' -> return i
                    else -> {
                        if (ch == escapeChar) i++
                        i++
                    }
                }
            }
            return -1
        }

        /**
         * 搜索下一个匹配的花括号，但引号内的花括号被跳过
         *
         * @param str
         * 需要搜索括号的原串
         * @param start
         * 起始位置,即左花括号在原串中的位置
         * @param escapeChar
         * 转义字符
         * @return 若找到,则返回匹配的右花括号在原串中的位置,否则返回-1
         */
        /**
         * 搜索下一个匹配的花括号,缺省转义字符为\，且引号内的花括号被跳过
         *
         * @param str
         * 需要搜索括号的原串
         * @param start
         * 起始位置,即左花括号(在原串中的位置
         * @return 若找到,则返回匹配的右花括号在原串中的位置,否则返回-1
         */
        @JvmOverloads
        fun scanBrace(str: String, start: Int, escapeChar: Char = '\\'): Int {
            if (str[start] != '{') return -1

            val len = str.length
            var i = start + 1
            while (i < len) {
                val ch = str[i]
                when (ch) {
                    '{' -> {
                        i = scanBrace(str, i, escapeChar)
                        if (i < 0) return -1
                        i++
                    }

                    '\"', '\'' -> {
                        val q = scanQuotation(str, i, escapeChar)
                        if (q < 0) {
                            i++
                        } else {
                            i = q + 1
                        }
                    }

                    '}' -> return i
                    else -> {
                        if (ch == escapeChar) i++
                        i++
                    }
                }
            }
            return -1
        }


        /**
         * 将原串中的空白字符删除,并根据ifcase参数将原串中的非引号内字符大写,小写或不动,缺省转义字符为\
         *
         * @param str
         * 需要删除空白字符的原串
         * @param ifcase
         * 可以为0, UPPER_WHEN_TRIM, LOWER_WHEN_TRIM,
         * UPPER_WHEN_TRIM+LOWER_WHEN_TRIM
         * @return 删除空白字符后的串
         */
        @JvmOverloads
        fun trim(str: String, ifcase: Int, escapeChar: Char = '\\'): String {
            var idx = 0
            val len = str.length
            var flag = 0
            // 0 - ignore following whitespace
            // 1 - identifier char
            // 2 - whitespace
            val dst = StringBuilder(len)
            while (idx < len) {
                val ch = str[idx]
                if ((ch == '\"' || ch == '\'')
                    && ((idx > 0 && str[idx - 1] != escapeChar) || idx == 0)
                ) {
                    if (flag == 2) dst.append(' ')
                    var i = scanQuotation(str, idx, escapeChar)
                    if (i < 0) throw RuntimeException("未找到位置" + idx + "处对应的引号")
                    i++
                    for (j in idx until i) dst.append(str[j])
                    idx = i
                    continue
                } else if (ch.isWhitespace()) {
                    do {
                        idx++
                    } while (idx < len && str[idx].isWhitespace())
                    if (flag > 0) flag = 2
                    continue
                } else if (isWordChar(ch)) {
                    if (flag == 2) dst.append(' ')
                    flag = 1
                } else {
                    flag = 0
                }
                when (ifcase) {
                    UPPER_WHEN_TRIM -> dst.append(ch.uppercaseChar())
                    LOWER_WHEN_TRIM -> dst.append(ch.lowercaseChar())
                    else -> dst.append(ch)
                }
                idx++
            }

            return dst.toString()
        }

        /**
         * 在原串中搜索短语,缺省转义字符为\
         *
         * @param str
         * 需要搜索短语的原串
         * @param phrase
         * 需要搜索的短语
         * @param start
         * 在原串中的起始位置
         * @param flag
         * 可以为0,IGNORE_CASE,IGNORE_PARS及其加法组合
         * @return 若找到,则返回短语在原串中的位置,否则返回-1
         */
        @JvmOverloads
        fun phraseAt(
            str: String, phrase: String, start: Int, flag: Int,
            escapeChar: Char = '\\',
        ): Int {
            val slen = str.length
            val plen = phrase.length
            var iswordchar = false
            var i = start
            while (i < slen) {
                val ch = str[i]
                if ((ch == '\"' || ch == '\'')
                    && ((i > 0 && str[i - 1] != '\\') || i == 0)
                ) {
                    i = scanQuotation(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    iswordchar = false
                    continue
                }
                if ((flag and IGNORE_PARS) == 0 && ch == '(') {
                    i = scanParenthesis(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    iswordchar = false
                    continue
                }
                if (!iswordchar) {
                    if (phrase.regionMatches(
                            0, str, i,
                            plen, ignoreCase = (flag and IGNORE_CASE) > 0
                        )
                    ) {
                        if ((i + plen) >= slen || !isWordChar(str[i + plen])) return i
                    }
                }
                iswordchar = isWordChar(ch)
                i++
            }
            return -1
        }

        /**
         * 替换原串中的子串,缺省转义字符为\
         *
         * @param str
         * 需要替换的原串
         * @param start
         * 对原串开始替换的起始位置
         * @param sold
         * 需要替换的子串
         * @param snew
         * 替换串
         * @param flag
         * 可为0,IGNORE_CASE,IGNORE_PARS,ONLY_FIRST,ONLY_PHRASE及其加法组合
         * @return 替换后的串
         */
        @JvmOverloads
        fun replace(
            str: String, start: Int, sold: String,
            snew: String?, flag: Int, escapeChar: Char = '\\',
        ): String {
            val strlen = str.length
            val len = sold.length
            var dst: StringBuilder? = null
            var preChar = '*' // 指示匹配串前一个字符不是有效标识符字符
            var i = start
            while (i < strlen) {
                val ch = str[i]
                if ((ch == '\'' || ch == '\"') && ((flag and IGNORE_QUOTE) == 0
                            ) && (i == 0 || (i > 0 && str[i - 1] != escapeChar))
                ) {
                    var idx = scanQuotation(str, i, escapeChar)
                    if (idx < 0) throw RuntimeException("未找到位置" + i + "处对应的引号")
                    idx++
                    if (dst != null) for (j in i until idx) dst.append(str[j])
                    i = idx
                    preChar = '*'
                    continue
                }
                if (((flag and IGNORE_PARS) == 0) && (ch == '(')) {
                    var idx = scanParenthesis(str, i, escapeChar)
                    if (idx < 0) throw RuntimeException("未找到位置" + i + "处对应的圆括号")
                    idx++
                    if (dst != null) for (j in i until idx) dst.append(str[j])
                    i = idx
                    preChar = '*'
                    continue
                }
                var lb: Boolean
                lb = sold.regionMatches(0, str, i, len, ignoreCase = (flag and IGNORE_CASE) > 0)
                if (lb && (flag and ONLY_PHRASE) > 0) {
                    // 被匹配串的第一字符及前一字符有一个不是标识符字符时为真
                    lb = !isWordChar(sold[0]) || !isWordChar(preChar)
                    // 被匹配串的最后字符及后一字符有一个不是标识符字符时
                    if ((i + len) < strlen) lb = (lb
                            && (!isWordChar(sold[len - 1]) || !isWordChar(
                        str[i + len]
                    )))
                }
                if (lb) {
                    if (dst == null) {
                        dst = StringBuilder(strlen shl 2)
                        for (j in 0 until i) dst.append(str[j])
                    }
                    dst.append(snew)
                    i += len
                    preChar = str[i - 1]
                    if ((flag and ONLY_FIRST) > 0) {
                        while (i < strlen) dst.append(str[i++])
                        break
                    }
                } else {
                    dst?.append(ch)
                    preChar = ch
                    i++
                }
            } // while(i<strlen)

            return if ((dst == null)) str else dst.toString()
        }

        /**
         * 替换原串中的子串,缺省转义字符为\
         *
         * @param str
         * 需要替换的原串
         * @param sold
         * 需要替换的子串
         * @param snew
         * 替换串
         * @param flag
         * 可为0,IGNORE_CASE,IGNORE_PARS,ONLY_FIRST,ONLY_PHRASE及其加法组合
         * @return 替换后的串
         */
        fun replace(str: String, sold: String, snew: String?, flag: Int): String {
            return replace(str, 0, sold, snew, flag, '\\')
        }

        /**
         * 在原串中搜索字符串(可以被包含中短语中)
         *
         * @param phrase
         * 需要搜索的字符串
         * @param start
         * 在原串中的起始位置
         * @param flag
         * 可以为0,IGNORE_CASE,IGNORE_PARS,IGNORE_CASE+IGNORE_PARS
         * @return 字符串在原串中的位置
         */
        @JvmOverloads
        fun indexOf(
            str: String, find: String, start: Int, flag: Int,
            escapeChar: Char = '\\',
        ): Int {
            val slen = str.length
            val plen = find.length
            var i = start
            while (i < slen) {
                val ch = str[i]
                if ((flag and IGNORE_QUOTE) == 0 &&  // xq add,加上支持引号内搜索 2010.8.25
                    (ch == '\"' || ch == '\'')
                    && ((i > 0 && str[i - 1] != '\\') || i == 0)
                ) {
                    i = scanQuotation(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    continue
                }
                if ((flag and IGNORE_PARS) == 0 && ch == '(') {
                    i = scanParenthesis(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    continue
                }
                if (find.regionMatches(0, str, i, plen, ignoreCase = (flag and IGNORE_CASE) > 0)) {
                    return i
                }
                i++
            }
            return -1
        }

        /**
         * 集算器查找专用，为了支持ONLY_PHRASE（wunan） 在原串中搜索字符串(可以被包含中短语中)
         *
         * @param phrase
         * 需要搜索的字符串
         * @param start
         * 在原串中的起始位置
         * @param flag
         * 可以为0,IGNORE_CASE,IGNORE_PARS,IGNORE_CASE+IGNORE_PARS
         * @return 字符串在原串中的位置
         */
        fun indexOf(str: String, start: Int, find: String, flag: Int): Int {
            val escapeChar = '\\'
            val slen = str.length
            val plen = find.length
            var preChar = '*'
            var i = start
            while (i < slen) {
                val ch = str[i]
                if ((flag and IGNORE_QUOTE) == 0 &&  // 加上支持引号内搜索 2018.10.9 wunan
                    (ch == '\"' || ch == '\'')
                    && ((i > 0 && str[i - 1] != '\\') || i == 0)
                ) {
                    i = scanQuotation(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    preChar = ch
                    continue
                }
                if ((flag and IGNORE_PARS) == 0 && (ch == '\"' || ch == '\'')
                    && ((i > 0 && str[i - 1] != '\\') || i == 0)
                ) {
                    i = scanQuotation(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    preChar = ch
                    continue
                }
                if ((flag and IGNORE_PARS) == 0 && ch == '(') {
                    i = scanParenthesis(str, i, escapeChar)
                    if (i < 0) return -1
                    i++
                    preChar = ch
                    continue
                }
                if (find.regionMatches(0, str, i, plen, ignoreCase = (flag and IGNORE_CASE) > 0)) {
                    if ((flag and ONLY_PHRASE) > 0) {
                        // 被匹配串的第一字符及前一字符有一个不是标识符字符时为真
                        var lb = (!isWordChar(find[0])
                                || !isWordChar(preChar))
                        // 被匹配串的最后字符及后一字符有一个不是标识符字符时
                        if ((i + plen) < slen) lb = (lb
                                && (!isWordChar(find[plen - 1]) || !isWordChar(
                            str[i + plen]
                        )))
                        if (!lb) {
                            preChar = ch
                            i++
                            continue
                        }
                    }
                    return i
                }
                i++
                preChar = ch
            }
            return -1
        }

        /**
         * 从后往前查找字符串，做引号、括号匹配
         * @param src 源串
         * @param find 要查找的串
         * @return 找不到返回-1
         */
        fun lastIndexOf(src: String, find: String): Int {
            var end = src.length - 1
            val findLen = find.length

            if (findLen == 1) {
                val tc = find[0]
                while (end >= 0) {
                    val c = src[end]
                    if (c == tc) {
                        if (end > 0 && src[end - 1] == '\\') {
                            break
                        } else {
                            return end
                        }
                    } else if (c == '"' || c == '\'' || c == ')' || c == ']' || c == '}' || c == '\\') {
                        // 从头开始找匹配
                        break
                    } else {
                        end--
                    }
                }
            }

            var pos = -1
            var i = 0
            var match = -1
            while (i <= end) {
                val c = src[i]
                when (c) {
                    '"', '\'' -> {
                        match = scanQuotation(src, i, '\\')
                        if (match == -1) {
                            return -1
                        } else {
                            i = match + 1
                            continue  // 跳过引号内的内容
                        }
                    }

                    '(' -> {
                        match = scanParenthesis(src, i, '\\')
                        if (match == -1) {
                            return -1
                        } else {
                            i = match + 1
                            continue  // 跳过扩号内的内容
                        }
                    }

                    '[' -> {
                        match = scanBracket(src, i, '\\')
                        if (match == -1) {
                            return -1
                        } else {
                            i = match + 1
                            continue  // 跳过扩号内的内容
                        }
                    }

                    '{' -> {
                        match = scanBrace(src, i, '\\')
                        if (match == -1) {
                            return -1
                        } else {
                            i = match + 1
                            continue  // 跳过扩号内的内容
                        }
                    }

                    '\\' -> {
                        i += 2
                        continue
                    }
                }
                if (src.startsWith(find, i)) {
                    pos = i
                    i += findLen
                } else {
                    i++
                }
            }

            return pos
        }

        fun isWordChar(ch: Char): Boolean {
             return ch.isLetterOrDigit()
            /*return (java.lang.Character.isJavaIdentifierStart(ch)
                    || java.lang.Character.isJavaIdentifierPart(ch))*/
        }

        //查找下一个\r或\n的位置，未找到返回长度
        private fun scanCRLF(str: String, start: Int): Int {
            var start = start
            val len = str.length
            while (start < len) {
                val ch = str[start]
                if (ch == '\r' || ch == '\n') return start
                start++
            }
            return len
        }

        //查找*/的位置，未找到返回长度
        private fun scanCommentEnd(str: String, start: Int): Int {
            var start = start
            val len = str.length
            while (start < len) {
                val ch = str[start]
                if (ch == '*' && start < len - 1 && str[start + 1] == '/') return start
                start++
            }
            return len
        }

        /**
         * 删除串中java风格的行注释和段落注释
         */
        fun removeComment(str: String): String {
            var idx = 0
            val len = str.length
            val buf = StringBuilder(len)
            while (idx < len) {
                val ch = str[idx]
                if (ch == '\'' || ch == '\"') {
                    val tmp = scanQuotation(str, idx)
                    if (tmp < 0) {
                        buf.append(str.substring(idx))
                        break
                    } else {
                        buf.append(str.substring(idx, tmp + 1))
                        idx = tmp + 1
                    }
                } else if (ch == '/') {
                    if (idx == len - 1) {
                        buf.append('/')
                        break
                    }
                    val ch2 = str[idx + 1]
                    if (ch2 == '/') {
                        idx = scanCRLF(str, idx + 2) //位置不加，后续回车换行需输出
                    } else if (ch2 == '*') {
                        idx = scanCommentEnd(str, idx + 2) + 2
                    } else {
                        buf.append('/')
                        idx++
                    }
                } else {
                    buf.append(ch)
                    idx++
                }
            }
            return buf.toString()
        }

        /*@Throws(java.lang.Exception::class)
        @JvmStatic
        fun main(args: Array<String>) {
            val buf: java.lang.StringBuffer = java.lang.StringBuffer()
            val br: java.io.BufferedReader = java.io.BufferedReader(java.io.FileReader("d:\\1.txt"))
            while (true) {
                val line: String = br.readLine() ?: break
                buf.append(line).append("\r\n")
            }
            br.close()
            val s = removeComment(buf.toString())
            println(s)
            println("..." + java.lang.System.getProperty("line.separator"))
        }*/
    }
}